<template>
  <el-upload
    class="file-upload"
    action=""
    :file-list="fileList"
    multiple
    :auto-upload="false"
    :on-change="onChange"
    :on-remove="onRemove"
  >
    <slot />
  </el-upload>
</template>

<script>
export default {
  name: 'FileUpload',
  model: {
    prop: 'url',
    event: 'change',
  },
  props: {
    action: {
      type: String,
      default: '/common/file/upload',
    },
    url: String,
    limit: {
      type: Number,
      default: 3,
    },
  },
  watch: {
    url(val) {
      const urlList = val ? val.split(',') : [];
      if (urlList.length > this.fileList.length) {
        this.fileList = urlList.map((item) => {
          return {
            url: this.fileBaseUrl + item,
            name: item,
          };
        });
      } else {
        urlList.forEach((item, index) => {
          if (!item.startsWith('blob')) {
            this.fileList[index] = {
              url: this.fileBaseUrl + item,
              name: item,
            };
          }
        });
      }
    },
  },
  data() {
    return {
      fileBaseUrl: '',
      fileList: [],
    };
  },
  methods: {
    onChange(file) {
      const list = this.fileList.concat([file]);
      this.fileList = list.length > this.limit ? list.slice(-this.limit) : list;
      const urlList = this.fileList.map((item) => {
        item.url = item.url
          ? item.url.replace(this.fileBaseUrl, '')
          : URL.createObjectURL(item.raw);
        return item.url;
      });
      this.$emit('change', urlList.join(','));
    },
    onRemove(file, fileList) {
      this.fileList = fileList;
      const urlList = fileList.map((item) => {
        return item.url.replace(this.fileBaseUrl, '');
      });
      this.$emit('change', urlList.join(','));
    },
    clear() {
      this.fileList = [];
    },
    submit() {
      return new Promise((resolve, reject) => {
        const uploadList = this.fileList.filter((item) => item.url.startsWith('blob'));
        let urlList = this.fileList
          .filter((item) => !item.url.startsWith('blob'))
          .map((item) => {
            return item.url
              ? item.url.replace(this.fileBaseUrl, '')
              : URL.createObjectURL(item.raw);
          });
        if (uploadList.length > 0) {
          const formData = new FormData();
          uploadList.forEach((file) => {
            formData.append('files', file.raw);
          });
          this.$http({
            method: 'post',
            url: this.$http.adornUrl(this.action),
            headers: { 'Content-Type': 'multipart/form-data' },
            data: formData,
          })
            .then(({ data }) => {
              urlList = urlList.concat(data.data.split(',').filter((item) => item));
              this.$emit('change', urlList.join(','));
              resolve();
            })
            .catch((e) => {
              reject(e);
            });
        } else {
          this.$emit('change', urlList.join(','));
          resolve();
        }
      });
    },
  },
};
</script>

<style lang="less" scoped>
.file-upload /deep/ .el-upload-list__item {
  transition: none !important;
}
</style>
